﻿using Common.Library;
using Common.Model;
using Dapper.Library;
using DevOps.Model;
using Network.Library;
using Redis.Library;
using Serialize.Library;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace DevOps.Logic
{
    /// <summary>
    /// 公用操作类
    /// </summary>
    public class OperationLogicImpl
    {
        /// <summary>
        /// 添加日志记录
        /// </summary>
        /// <param name="func_type">功能类型 100：插入操作  101：更新操作 102：删除操作</param>
        /// <param name="business_title">业务标题【用户管理】</param>
        /// <param name="detail">操作明细</param>
        /// <param name="user_id">用户ID</param>
        public void AddOperationLog(OperationLogType func_type, BusinessTitleType business_title, string detail, string user_id = "")
        {
            string clientIp = HttpHelper.GetIP();
            Task.Run(() =>
            {
                var user = GetLoginUserInfo(user_id);
                using (var con = DataBase.GetConnection(DatabaseName.Sql_BUS_DB.ToString()))
                {
                    SysOperationLogInfoEntity logInfoEntity = new SysOperationLogInfoEntity
                    {
                        service_name = ServiceName.DevOpsService.GetEnumItemDescription(),
                        business_title = business_title.GetEnumItemDescription(),
                        detail = detail,
                        func_type = (int)func_type,
                        ip_address = clientIp,
                        user_code = user.id,
                        user_name = user.realname
                    };
                    var result = con.CommandSet<SysOperationLogInfoEntity>().InsertAsync(logInfoEntity);
                }
            });
        }

        /// <summary>
        /// 获取登录人员信息
        /// </summary>
        /// <returns></returns>
        public UserLoginInfo GetLoginUserInfo(string user_id = "")
        {
            var resultInfo = new UserLoginInfo();
            string userId = string.Empty;
            if (user_id.IsNullOrEmpty())
            {
                userId = HttpHelper.GetJwtUserId();
            }
            else
            {
                userId = user_id;
            }
            string userStr = RedisClient.GetRedisDb(RedisAuthorityInfo.RedisDbWeb).StringGet(RedisAuthorityInfo.RedisSessionCode + userId);
            if (!string.IsNullOrEmpty(userStr))
            {
                resultInfo = JsonHelper.JsonToObject<UserLoginInfo>(userStr);
            }
            return resultInfo;
        }

        /// <summary>
        /// 指定ID ，向下查询FunctionCfg所有的子节点------递归获取
        /// </summary>
        /// <param name="orgList"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public List<MenuInfo> GetFunctionChildTreeInfo(List<FunctionCfgInfoResponse> orgList, string parentId)
        {
            List<MenuInfo> reultList = new List<MenuInfo>();

            //根据NodeID，获取当前子节点列表
            MenuInfo treeInfo = null;

            List<FunctionCfgInfoResponse> chidList = orgList.FindAll(p => p.parent_id == parentId).ToList();

            if (chidList.Count > 0)
            {
                foreach (var item in chidList)
                {
                    treeInfo = new MenuInfo()
                    {
                        id = item.id,
                        name = item.name,
                        link_url = item.link_url,
                        target = item.target,
                        is_spread = item.is_spread,
                        icon_font = item.icon_font,
                        sort = item.sort,
                        application_name = item.application_name,
                        application_ids = item.application_ids,
                        function_type = item.function_type,
                        function_name = int.Parse(item.function_type).GetEnumDescriptionByValue(typeof(FunctionType)),
                        is_valid = item.is_valid,
                        have_elder = item.have_elder,
                        have_younger = item.have_younger,
                        children = new List<MenuInfo>()
                    };
                    //递归获取下一级
                    treeInfo.children = GetFunctionChildTreeInfo(orgList, item.id);
                    reultList.Add(treeInfo);
                }
            }
            return reultList;
        }

        /// <summary>
        /// 指定ID ，向下查询FunctionCfg所有的子节点------递归获取
        /// </summary>
        /// <param name="orgList"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public List<MenuTreeInfo> GetFunctionChildTreeInfo(List<FunctionCfgRoleMenuResponse> orgList, string parentId)
        {
            List<MenuTreeInfo> reultList = new List<MenuTreeInfo>();

            //根据NodeID，获取当前子节点列表
            MenuTreeInfo treeInfo = null;

            List<FunctionCfgRoleMenuResponse> chidList = orgList.FindAll(p => p.parent_id == parentId).ToList();

            if (chidList.Count > 0)
            {
                foreach (var item in chidList)
                {
                    treeInfo = new MenuTreeInfo()
                    {
                        id = item.id,
                        name = item.name,
                        link_url = item.link_url,
                        target = item.target,
                        is_spread = item.is_spread,
                        icon_font = item.icon_font,
                        sort = item.sort,
                        application_name = item.application_name,
                        application_ids = item.application_ids,
                        function_type = item.function_type,
                        function_name = int.Parse(item.function_type).GetEnumDescriptionByValue(typeof(FunctionType)),
                        lay_is_checked = item.lay_is_checked,
                        children = new List<MenuTreeInfo>()
                    };
                    //递归获取下一级
                    treeInfo.children = GetFunctionChildTreeInfo(orgList, item.id);
                    reultList.Add(treeInfo);
                }
            }
            return reultList;
        }

        /// <summary>
        /// 指定ID ，向下查询FunctionCfg所有的子节点------递归获取
        /// </summary>
        /// <param name="orgList"></param>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public List<DepartmentTreeInfo> GetDepartmentChildTreeInfo(List<DepartmentResponse> orgList, string parentId)
        {
            List<DepartmentTreeInfo> reultList = new List<DepartmentTreeInfo>();
            //根据NodeID，获取当前子节点列表
            DepartmentTreeInfo treeInfo = null;

            List<DepartmentResponse> chidList = orgList.FindAll(p => p.parent_id == parentId).ToList();

            if (chidList.Count > 0)
            {
                foreach (var item in chidList)
                {
                    treeInfo = new DepartmentTreeInfo()
                    {
                        id = item.id,
                        parent_id = item.parent_id,
                        name = item.name,
                        sort = item.sort,
                        leader = item.leader,
                        phone = item.phone,
                        email = item.email,
                        remarks = item.remarks,
                        is_valid = item.is_valid,
                        have_elder = item.have_elder,
                        have_younger = item.have_younger,
                        children = new List<DepartmentTreeInfo>()
                    };
                    //递归获取下一级
                    treeInfo.children = GetDepartmentChildTreeInfo(orgList, item.id);
                    reultList.Add(treeInfo);
                }
            }
            return reultList;
        }

        /// <summary>
        /// 指定ID ，向下查询所有的子节点------递归获取[这里key是唯一标识符]==================================
        /// </summary>
        /// <param name="orgList"></param>
        /// <param name="parentId"></param>
        /// <param name="employees"></param>
        /// <param name="usedIdList">已经使用的ID</param>
        /// <returns></returns>
        public List<DepartmentUserTreeInfo> GetDepartmentUserTree(List<DepartmentTreeResponse> orgList, string parentId, List<UserTreeInfoResponse> employees, List<int> usedIdList)
        {
            List<DepartmentUserTreeInfo> reultList = new List<DepartmentUserTreeInfo>();

            //根据NodeID，获取当前子节点列表
            DepartmentUserTreeInfo treeInfo = null;
            List<DepartmentTreeResponse> chidList = orgList.FindAll(q => q.parent_id != null && q.parent_id == parentId).ToList();
            var parentInfo = orgList.Find(q => q.key == parentId);

            if (chidList.Count > 0)
            {
                foreach (var item in chidList)
                {
                    treeInfo = new DepartmentUserTreeInfo()
                    {
                        id = item.id,
                        pid = parentInfo != null ? parentInfo.id : 1,
                        key = item.key,
                        label = item.name,
                        type = 100,
                        children = new List<DepartmentUserTreeInfo>()
                    };

                    foreach (var employee in employees)
                    {
                        if (employee.department_ids.Contains(treeInfo.key))
                        {
                            if (usedIdList.Contains(employee.id))
                            {
                                Random ran = new Random();
                                int RandKey = ran.Next(1000, 9999);

                                treeInfo.children.Add(new DepartmentUserTreeInfo()
                                {
                                    id = employee.id + RandKey,
                                    key = employee.key,
                                    pid = treeInfo.id,
                                    label = employee.realname,
                                    type = 110,
                                    children = new List<DepartmentUserTreeInfo>()
                                });
                            }
                            else
                            {
                                usedIdList.Add(employee.id);

                                treeInfo.children.Add(new DepartmentUserTreeInfo()
                                {
                                    id = employee.id,
                                    key = employee.key,
                                    pid = treeInfo.id,
                                    label = employee.realname,
                                    type = 110,
                                    children = new List<DepartmentUserTreeInfo>()
                                });
                            }
                        }
                    }
                    //递归获取下一级
                    treeInfo.children.AddRange(GetDepartmentUserTree(orgList, item.key, employees, usedIdList));
                    reultList.Add(treeInfo);
                }
            }
            return reultList;
        }

        /// <summary>
        /// 根据参数关键字Key获取对应参数值
        /// </summary>
        /// <param name="parametersKey"></param>
        /// <returns></returns>
        public string GetParameterSettingByKey(string parametersKey)
        {
            string result = string.Empty;

            ParameterSettingServiceRedis.GetParameterSetting((resultInfo) =>
            {
                SysParameterSettingEntity ParameterSettingInfo = new SysParameterSettingEntity();

                if (resultInfo != null && resultInfo.Count > 0)
                {
                    ParameterSettingInfo = resultInfo.Find(p => p.parameters_key.Equals(parametersKey));

                    if (ParameterSettingInfo != null)
                    {
                        result = ParameterSettingInfo.parameters_value;
                    }
                    else
                    {
                        using (var con = DataBase.GetConnection(DatabaseName.Sql_BUS_DB.ToString()))
                        {
                            var ParameterSettingResult = con.QuerySet<SysParameterSettingEntity>().ToList();

                            //将参数信息，全部存入redis
                            ParameterSettingServiceRedis.SaveAllParameterSetting(ParameterSettingResult.Select(p => p.parameters_key).ToList(), ParameterSettingResult);

                            ParameterSettingInfo = ParameterSettingResult.Find(p => p.parameters_key.Equals(parametersKey));

                            if (ParameterSettingInfo != null)
                            {
                                result = ParameterSettingInfo.parameters_value;
                            }
                        }
                    }
                }
                else
                {
                    using (var con = DataBase.GetConnection(DatabaseName.Sql_BUS_DB.ToString()))
                    {
                        var ParameterSettingResult = con.QuerySet<SysParameterSettingEntity>().ToList();

                        //将参数信息，全部存入redis
                        ParameterSettingServiceRedis.SaveAllParameterSetting(ParameterSettingResult.Select(p => p.parameters_key).ToList(), ParameterSettingResult);

                        ParameterSettingInfo = ParameterSettingResult.Find(p => p.parameters_key.Equals(parametersKey));

                        if (ParameterSettingInfo != null)
                        {
                            result = ParameterSettingInfo.parameters_value;
                        }
                    }
                }
            });

            return result;
        }

        #region 公用逻辑

        /// <summary>
        /// 获取钉钉授权的access_token
        /// </summary>
        /// <returns></returns>
        public string GetDingAccessToken()
        {
            string result = string.Empty;

            AttendanceServiceRedis.GetDindinAccessToken(RedisCommonInfo.RedisAttendance, (resultInfo) =>
            {
                if (resultInfo != null && resultInfo.IsNotNullOrEmpty())
                {
                    result = resultInfo;
                }
                else
                {
                    //1、获取access_token
                    //var dindinAppKey = GetParameterSettingByKey(ParameterSettingInfo.DingAppKey);
                    //var dindinAppSecret =  GetParameterSettingByKey(ParameterSettingInfo.DingAppSecret);
                    var accessTokenInfo = "";//  HttpProtocolHelper.SendGetRequestAsString(string.Format(DindinHttpUrls.GettokenUrl, dindinAppKey, dindinAppSecret));
                    var tokenInfo = accessTokenInfo.JsonToObject<DingGettokenResponse>();
                    //如果有问题重复一次
                    if (tokenInfo.errmsg == "ok")
                    {
                        result = tokenInfo.access_token;
                        AttendanceServiceRedis.SaveDindinAccessToken(RedisCommonInfo.RedisAttendance, tokenInfo.access_token);
                    }
                    else
                    {
                        accessTokenInfo = "";// HttpProtocolHelper.SendGetRequestAsString(string.Format(DindinHttpUrls.GettokenUrl, dindinAppKey, dindinAppSecret));
                        tokenInfo = accessTokenInfo.JsonToObject<DingGettokenResponse>();
                        if (tokenInfo.errmsg == "ok")
                        {
                            result = tokenInfo.access_token;
                            AttendanceServiceRedis.SaveDindinAccessToken(RedisCommonInfo.RedisAttendance, tokenInfo.access_token);
                        }
                    }
                }
            });
            return result;
        }


        /// <summary>
        /// 根据用户Id，获取上级部门领导Id
        /// </summary>
        /// <param name="userInfo">用户</param>
        /// <param name="type">120部门领导 130上级部门领导 140所有上级部门领导</param>
        /// <returns></returns>
        public List<View_SysUserEntity> GetDepartmentLeader(UserLoginInfo userInfo, int type)
        {
            List<View_SysUserEntity> returnLeaders = new List<View_SysUserEntity>();

            using (var con = DataBase.GetConnection(DatabaseName.Sql_BUS_DB.ToString()))
            {
                con.Transaction(tran =>
                {
                    //获取所有部门
                    var departmentInfos = tran.QuerySet<SysDepartmentInfoEntity>().Where(p => p.is_deleted == false).ToList();

                    //获取所有部门领导
                    var departmentLeaders = tran.QuerySet<SysLeaderDepartmentReEntity>().ToList();

                    var allUser = tran.QuerySet<View_SysUserEntity>().ToList();

                    //当前部门
                    var departmentInfo = departmentInfos.Find(p => p.id == userInfo.department_ids);

                    //可选的人员
                    returnLeaders = RecursionLeaders(type,allUser,departmentInfos, departmentLeaders, departmentInfo);

                });
            }
            return returnLeaders;
        }

        /// <summary>
        /// 递归获取部门领导
        /// </summary>
        /// <param name="type">120部门领导 130上级部门领导 140所有上级部门领导</param>
        /// <param name="allUser">所有的用户</param>
        /// <param name="departmentInfos">所有的部门</param>
        /// <param name="departmentLeaders">所有的领导</param>
        /// <param name="departmentInfo">当前部门</param>
        /// <returns></returns>
        private List<View_SysUserEntity> RecursionLeaders(int type, List<View_SysUserEntity> allUser, List<SysDepartmentInfoEntity> departmentInfos,List<SysLeaderDepartmentReEntity> departmentLeaders, SysDepartmentInfoEntity departmentInfo) {

            List<View_SysUserEntity> returnLeaders = new List<View_SysUserEntity>();

            if (type == (int)FlowHandlerType.DepartmentHead)
            {
                //部门领导
                var leaders = departmentLeaders.Where(p => p.department_id == departmentInfo.id).Select(p=>p.user_id).ToList();
                if (leaders.Count > 0)
                {
                    var users = allUser.FindAll(p => leaders.ToArray().Contains(p.id)).ToList();
                    returnLeaders.AddRange(users);
                }
                else
                {
                    //当前部门找不到领导，到上级部门去找
                    var parentDepartment = departmentInfos.Find(p => p.id == departmentInfo.parent_id);
                    if (parentDepartment != null)
                    {
                        var users = RecursionLeaders(type, allUser,departmentInfos, departmentLeaders, parentDepartment);
                        returnLeaders.AddRange(users);
                    }
                }
            }
            else if (type == (int)FlowHandlerType.SuperiorHead)
            {
                //部门领导
                var leaders = departmentLeaders.Where(p => p.department_id == departmentInfo.id).ToList();
                if (leaders.Count > 0)
                {
                    var parentDepartment = departmentInfos.Find(p => p.id == departmentInfo.parent_id);
                    var users = RecursionLeaders((int)FlowHandlerType.DepartmentHead,allUser,departmentInfos, departmentLeaders, parentDepartment);
                    returnLeaders.AddRange(users);
                }
                else
                {
                    //当前部门找不到领导，到上级部门去找
                    var parentDepartment = departmentInfos.Find(p => p.id == departmentInfo.parent_id);
                    if (parentDepartment != null)
                    {
                        var users = RecursionLeaders(type,allUser,departmentInfos,departmentLeaders, parentDepartment);
                        returnLeaders.AddRange(users);
                    }
                }
            }
            else {
                //部门领导
                var leaders = departmentLeaders.Where(p => p.department_id == departmentInfo.id).Select(p => p.user_id).ToList();
                if (leaders.Count > 0)
                {
                    var users = allUser.Where(p => p.id.In(leaders.ToArray())).ToList();
                    returnLeaders.AddRange(users);
                }
                else
                {
                    //当前部门找不到领导，到上级部门去找
                    var parentDepartment = departmentInfos.Find(p => p.id == departmentInfo.parent_id);
                    if (parentDepartment!=null)
                    {
                        var users = RecursionLeaders(type, allUser, departmentInfos, departmentLeaders, parentDepartment);
                        returnLeaders.AddRange(users);
                    }
                }
            }
            return returnLeaders;
        }
        
        #endregion

    }
}
